package com.psytech.app.task.web_ui.client;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.psytech.app.task.web_ui.shared.UIComment;
import com.psytech.app.task.web_ui.shared.UIGroup;
import com.psytech.app.task.web_ui.shared.UIUser;
import com.psytech.app.task.web_ui.shared.UiTask;
import com.psytech.app.task.web_ui.shared.UiTask.PRIORITY;
import com.psytech.app.task.web_ui.shared.UiTask.STATUS;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.fields.DataSourceDateField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.DateDisplayFormat;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.DateItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextAreaItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Webui implements EntryPoint {

	private static Logger LOG = Logger.getLogger(Webui.class.getName());
	private static final WebuiMessages messages = GWT.create(WebuiMessages.class);

	private static final int LIST_WIDTH = 1220;

	private static final WebuiConstants CONSTANTS = GWT.create(WebuiConstants.class);
	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = messages.networkWarning();
	/**
	 * This is the entry point method.
	 */

	private static final VerticalPanel mainPanel = new VerticalPanel();

	// Liste des tâches
	private static final ListGrid taskGrid = new ListGrid() {
		@Override
		protected Canvas createRecordComponent(final ListGridRecord record, final Integer colNum) {
			final String fieldName = this.getFieldName(colNum);
			if (fieldName.equals("editButton")) {

				final HLayout recordCanvas = new HLayout(3);
				recordCanvas.setHeight(28);
				final ImgButton editbutton = new ImgButton();
				editbutton.setHeight(14);
				editbutton.setWidth(14);
				editbutton.setShowDown(false);
				editbutton.setShowRollOver(false);
				editbutton.setLayoutAlign(Alignment.CENTER);
				editbutton.setSrc(GWT.getModuleBaseURL() + "edit-icon.png");
				editbutton.setTooltip(messages.editTask());
				editbutton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {
					@Override
					public void onClick(final com.smartgwt.client.widgets.events.ClickEvent event) {
						async.searchTaskByUID(record.getAttributeAsString("uid"), new AsyncCallback<UiTask>() {
							@Override
							public void onFailure(final Throwable caught) {
								alert(caught.getMessage());
							}

							@Override
							public void onSuccess(final UiTask result) {
								editTask(new TaskRecord(result));
							}
						});

					}
				});

				final ImgButton deleteButton = new ImgButton();
				deleteButton.setHeight(26);
				deleteButton.setWidth(26);
				deleteButton.setShowDown(false);
				deleteButton.setShowRollOver(false);
				deleteButton.setLayoutAlign(Alignment.CENTER);
				deleteButton.setSrc(GWT.getModuleBaseURL() + "button-cross-big.gif");
				deleteButton.setTooltip(messages.deleteTask());
				deleteButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {

					@Override
					public void onClick(final com.smartgwt.client.widgets.events.ClickEvent event) {
						if (Window.confirm(messages.deleteTaskWarn())) {
							async.removeTask(record.getAttributeAsString("uid"), new AsyncCallback<Void>() {
								@Override
								public void onFailure(final Throwable caught) {
									alert(caught.getMessage());
								}

								@Override
								public void onSuccess(final Void result) {
									refreshTaskList(selectedUser);
								}
							});
						}
					}
				});

				final ImgButton commentButton = new ImgButton();
				commentButton.setHeight(16);
				commentButton.setWidth(16);
				commentButton.setShowDown(false);
				commentButton.setShowRollOver(false);
				commentButton.setLayoutAlign(Alignment.CENTER);
				commentButton.setSrc(GWT.getModuleBaseURL() + "commentaire.png");
				commentButton.setTooltip(messages.addComment());
				commentButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {

					@Override
					public void onClick(final com.smartgwt.client.widgets.events.ClickEvent event) {
						showComments(record.getAttributeAsString("uid"));
					}
				});

				recordCanvas.addMember(editbutton);
				recordCanvas.addMember(commentButton);
				recordCanvas.addMember(deleteButton);
				return recordCanvas;

			} else
				return null;
		}
	};

	// Liste des commentaires
	final static ListGrid commentGrid = new ListGrid() {
		@Override
		protected Canvas createRecordComponent(final ListGridRecord record, final Integer colNum) {
			final String fieldName = this.getFieldName(colNum);
			if (fieldName.equals("deleteButton")) {
				final ImgButton deleteButton = new ImgButton();
				deleteButton.setHeight(26);
				deleteButton.setWidth(26);
				deleteButton.setShowDown(false);
				deleteButton.setShowRollOver(false);
				deleteButton.setLayoutAlign(Alignment.CENTER);
				deleteButton.setSrc(GWT.getModuleBaseURL() + "button-cross-big.gif");
				deleteButton.setTooltip(messages.deleteTask());
				deleteButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {

					@Override
					public void onClick(final com.smartgwt.client.widgets.events.ClickEvent event) {
						if (Window.confirm(messages.deleteCommentWarn())) {
							async.deleteComment(record.getAttributeAsString("uid"), new AsyncCallback<Void>() {

								@Override
								public void onSuccess(final Void result) {
									listComments(commentGrid, record.getAttributeAsString("taskUid"));
								}

								@Override
								public void onFailure(final Throwable caught) {
									alert(caught.getMessage());
								}
							});
						}
					}
				});
				return deleteButton;
			} else
				return null;
		}
	};

	private static DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("dd/MM/yy");

	private static CellFormatter getCellDateFormater(final String fieldName) {
		return new CellFormatter() {

			@Override
			public String format(final Object value, final ListGridRecord record, final int rowNum, final int colNum) {
				if (record.getAttributeAsDate(fieldName) != null)
					return dateTimeFormat.format(record.getAttributeAsDate(fieldName));
				else
					return null;
			}
		};
	}

	// Service distants
	private static final TaskManagerServiceAsync async = (TaskManagerServiceAsync) GWT.create(TaskManagerService.class);

	// Affichage des erreurs
	private static HTML errorDetails;
	private static DialogBox errorBox;

	private static UIUser connectedUser; // TODO improve avec un holder ?

	private static UIUser selectedUser;

	/*
	 * Link an uid to a UIUser
	 */
	private static Map<String, UIUser> teamMembersMap_uidToUser = new HashMap<String, UIUser>();

	/*
	 * Link a Login to a UIUser
	 */
	private static Map<String, UIUser> teamMembersMap_loginToUser = new HashMap<String, UIUser>();

	private static int FILTER = CONSTANTS.filterAffected();

	ListBox priorityListBox;
	ListBox statusListBox;
	private static ListBox teamMembersListBox = new ListBox();
	final ListBox groupListBox = new ListBox();

	@Override
	public void onModuleLoad() {
		// http://code.google.com/intl/fr-FR/webtoolkit/doc/latest/DevGuideCodeSplitting.html

		mainPanel.setSpacing(10);
		// mainPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		RootPanel.get("taskList").add(mainPanel);

		async.whoAmI(new AsyncCallback<UIUser>() {
			@Override
			public void onFailure(final Throwable exception) {
				alert(messages.errorLabel() + "whoAmi : " + exception.getMessage());
			}

			@Override
			public void onSuccess(final UIUser user) {
				connectedUser = user;
				final HTML userName = new HTML(messages.connectedUser("<b>" + user.getLogin() + "</b>"));
				RootPanel.get("connectedUser").add(userName);
				selectedUser = new UIUser();
				selectedUser.setUid(user.getUid());
				Webui.this.loadGroups();
			}
		});

	}

	public void loadGroups() {
		async.getGroups(connectedUser.getUid(), new AsyncCallback<List<UIGroup>>() {
			@Override
			public void onFailure(final Throwable arg0) {
				alert(arg0.getMessage());

			}

			@Override
			public void onSuccess(final List<UIGroup> groups) {
				if (groups.size() == 1) {
					Webui.this.loadTeamMember(groups.get(0).getGuid());
				} else if (groups.size() > 1) {
					int i = 0;
					final String lastSelectedGroup = Cookies.getCookie(CONSTANTS.lastGroupCookieName()) != null ? Cookies
							.getCookie(CONSTANTS.lastGroupCookieName()) : "";
					for (final UIGroup group : groups) {
						Webui.this.groupListBox.addItem(group.getName());
						Webui.this.groupListBox.setValue(i, group.getGuid());
						if (group.getGuid().equals(lastSelectedGroup)) {
							Webui.this.groupListBox.setSelectedIndex(i);
						}
						i++;
					}
					Webui.this.groupListBox.addChangeHandler(new ChangeHandler() {
						@Override
						public void onChange(final ChangeEvent event) {
							final Date expirationDate = new Date();
							expirationDate.setTime(expirationDate.getTime() + CONSTANTS.cookieExpirationDelay());
							Cookies.setCookie(CONSTANTS.lastGroupCookieName(),
									Webui.this.groupListBox.getValue(Webui.this.groupListBox.getSelectedIndex()),
									expirationDate);
							Webui.this.loadTeamMember(Webui.this.groupListBox.getValue(Webui.this.groupListBox
									.getSelectedIndex()));
						}
					});

					// RootPanel.get("groups").add(list);
					Webui.this.loadTeamMember(Webui.this.groupListBox.getValue(Webui.this.groupListBox
							.getSelectedIndex()));
				}
				Webui.this.initTables();
			}
		});
	}

	/*
	 * Initialise les differente parties de l'IHM
	 */
	public void initTables() {
		mainPanel.clear();
		// boutton d'ouverture de boite de creation de tâche
		final Button createTaskButton = new Button(messages.createLabel());
		createTaskButton.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(final ClickEvent clickevent) {
				// openEditTaskBox(null);
				editTask(null);

			}
		});
		mainPanel.add(createTaskButton);

		// Creation du menu
		final VerticalPanel menu = new VerticalPanel();
		menu.addStyleName("filter-panel");
		menu.setWidth(LIST_WIDTH + "px");
		final VerticalPanel verticalPanel = new VerticalPanel();
		verticalPanel.setWidth("100%");

		final HorizontalPanel horizontalPanel = new HorizontalPanel();
		LOG.fine("Group List Item Number : " + this.groupListBox.getItemCount());
		if (this.groupListBox.getItemCount() > 0) {
			final HorizontalPanel groupsPanel = new HorizontalPanel();
			groupsPanel.add(this.groupListBox);
			groupsPanel.setStyleName("groupsPanel");
			horizontalPanel.add(groupsPanel);
		}
		final HTML teamMemberLabel = new HTML(messages.teamMemberLabel());
		teamMemberLabel.setStyleName("filter-labels");
		horizontalPanel.add(teamMemberLabel);

		horizontalPanel.add(teamMembersListBox);

		FILTER = Cookies.getCookie("filter") == null ? CONSTANTS.filterAffected() : Integer.parseInt(Cookies
				.getCookie("filter"));

		final HorizontalPanel radioPanel = new HorizontalPanel();
		radioPanel.setStyleName("radio");
		final RadioButton tasksAffectedToUser = new RadioButton("filter", messages.filterAffectedOnly());
		tasksAffectedToUser.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(final ClickEvent arg0) {
				FILTER = CONSTANTS.filterAffected();
				final Date expirationDate = new Date();
				expirationDate.setTime(expirationDate.getTime() + CONSTANTS.cookieExpirationDelay());
				Cookies.setCookie("filter", String.valueOf(FILTER), expirationDate);
				final UIUser selectedUser = new UIUser();
				selectedUser.setUid(teamMembersListBox.getValue(teamMembersListBox.getSelectedIndex()));
				refreshTaskList(selectedUser);
			}
		});
		radioPanel.add(tasksAffectedToUser);
		final RadioButton allUserTask = new RadioButton("filter", messages.filterAffectedAndOwned());
		allUserTask.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(final ClickEvent arg0) {
				FILTER = CONSTANTS.filterAffectedAndCreated();
				final Date expirationDate = new Date();
				expirationDate.setTime(expirationDate.getTime() + CONSTANTS.cookieExpirationDelay());
				Cookies.setCookie("filter", String.valueOf(FILTER), expirationDate);
				final UIUser selectedUser = new UIUser();
				selectedUser.setUid(teamMembersListBox.getValue(teamMembersListBox.getSelectedIndex()));
				refreshTaskList(selectedUser);
			}
		});
		radioPanel.add(allUserTask);

		final RadioButton unaffectedTask = new RadioButton("filter", messages.unaffectedTaskList());
		unaffectedTask.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(final ClickEvent arg0) {
				FILTER = CONSTANTS.filterUnaffected();
				final Date expirationDate = new Date();
				expirationDate.setTime(expirationDate.getTime() + CONSTANTS.cookieExpirationDelay());
				Cookies.setCookie("filter", String.valueOf(FILTER), expirationDate);
				refreshTaskList(selectedUser);
			}
		});
		radioPanel.add(unaffectedTask);

		final RadioButton allTask = new RadioButton("filter", messages.filterAllTeamTask());
		allTask.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(final ClickEvent arg0) {
				FILTER = CONSTANTS.filterAll();
				final Date expirationDate = new Date();
				expirationDate.setTime(expirationDate.getTime() + CONSTANTS.cookieExpirationDelay());
				Cookies.setCookie("filter", String.valueOf(FILTER), expirationDate);
				final UIUser selectedUser = new UIUser();
				selectedUser.setUid(teamMembersListBox.getValue(teamMembersListBox.getSelectedIndex()));
				refreshTaskList(selectedUser);
			}
		});
		radioPanel.add(allTask);

		if (FILTER == -1 || FILTER == CONSTANTS.filterAffected()) {
			tasksAffectedToUser.setValue(true);
		} else if (FILTER == CONSTANTS.filterAffectedAndCreated()) {
			allUserTask.setValue(true);
		} else if (FILTER == CONSTANTS.filterAll()) {
			allTask.setValue(true);
		} else if (FILTER == CONSTANTS.filterUnaffected()) {
			unaffectedTask.setValue(true);
		}

		horizontalPanel.add(radioPanel);
		horizontalPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
		final HorizontalPanel titleBar = new HorizontalPanel();
		titleBar.setStyleName("title");
		final HTML title = new HTML(messages.taskFilterTitle());
		title.setStyleName("title-text");
		titleBar.add(title);
		verticalPanel.add(titleBar);
		verticalPanel.add(horizontalPanel);
		menu.add(verticalPanel);

		mainPanel.add(menu);
		mainPanel.add(getSmartGwtCanvasTaskList());
	}

	public void loadTeamMember(final String groupUid) {

		async.getTeamMember(groupUid, new AsyncCallback<List<UIUser>>() {
			@Override
			public void onFailure(final Throwable arg0) {
				alert(arg0.getMessage());

			}

			@Override
			public void onSuccess(final List<UIUser> arg0) {
				teamMembersMap_uidToUser.clear();
				for (final UIUser uiUser : arg0) {
					teamMembersMap_uidToUser.put(uiUser.getUid(), uiUser);
					teamMembersMap_loginToUser.put(uiUser.getLogin(), uiUser);
				}
				refreshTeamMemberListBox();
			}
		});

	}

	private static void refreshTeamMemberListBox() {
		teamMembersListBox.clear();
		int i = 0;
		for (final UIUser user : teamMembersMap_uidToUser.values()) {
			LOG.fine("refreshTeamMemberListBox " + user.getLogin() + " " + user.getUid());
			teamMembersListBox.addItem(user.getLogin(), user.getUid());
			if (user.getUid().equals(connectedUser.getUid())) {
				teamMembersListBox.setSelectedIndex(i);
			}
			i++;
		}
		teamMembersListBox.addChangeHandler(new ChangeHandler() {

			@Override
			public void onChange(final ChangeEvent arg0) {
				selectedUser.setUid(teamMembersListBox.getValue(teamMembersListBox.getSelectedIndex()));
				LOG.fine("refreshTeamMemberListBox#onChange " + selectedUser.getUid());
				refreshTaskList(selectedUser);
			}
		});
	}

	private static void refreshTaskList(final UIUser user) {
		if (FILTER == CONSTANTS.filterAffectedAndCreated()) {
			async.listAllTask(user, new AsyncCallback<List<UiTask>>() {
				@Override
				public void onSuccess(final List<UiTask> arg0) {
					taskGrid.setData(TaskData.UITaskList2TaskRecordArray(arg0));
				}

				@Override
				public void onFailure(final Throwable arg0) {
					GWT.log("Erreur : " + arg0.getMessage());
					alert("Erreur : " + arg0.getMessage());
				}
			});
		} else if (FILTER == CONSTANTS.filterAffected()) {
			async.listAffectedTask(user, new AsyncCallback<List<UiTask>>() {
				@Override
				public void onSuccess(final List<UiTask> arg0) {
					taskGrid.setData(TaskData.UITaskList2TaskRecordArray(arg0));

				}

				@Override
				public void onFailure(final Throwable arg0) {
					GWT.log("Erreur : " + arg0.getMessage());
					alert("Erreur : " + arg0.getMessage());
				}
			});
		} else if (FILTER == CONSTANTS.filterUnaffected()) {
			async.listUnaffectedTask(new AsyncCallback<List<UiTask>>() {
				@Override
				public void onSuccess(final List<UiTask> arg0) {
					taskGrid.setData(TaskData.UITaskList2TaskRecordArray(arg0));
				}

				@Override
				public void onFailure(final Throwable arg0) {
					GWT.log("Erreur : " + arg0.getMessage());
					alert("Erreur : " + arg0.getMessage());
				}
			});
		} else if (FILTER == CONSTANTS.filterAll()) {
			async.listAllTeamTask(new AsyncCallback<List<UiTask>>() {
				@Override
				public void onSuccess(final List<UiTask> arg0) {
					taskGrid.setData(TaskData.UITaskList2TaskRecordArray(arg0));
				}

				@Override
				public void onFailure(final Throwable arg0) {
					GWT.log("Erreur : " + arg0.getMessage());
					alert("Erreur : " + arg0.getMessage());
				}
			});
		}

	}

	/**
	 * Ouvre la boite de dialogue permetant d'éditer ou créer une tâche.
	 * 
	 * @param taskRecord
	 *            tâche à éditer, si nulle alors la tâche sera créée
	 */

	private static void editTask(final TaskRecord taskRecord) {
		GWT.log(messages.editBoxTitle(taskRecord == null ? "une nouvelle tâche" : taskRecord.getInnerUiTask().getUid()));
		final DataSource dataSource = new DataSource();
		final DataSourceTextField nameField = new DataSourceTextField("name", messages.taskNameLabel(), 50, true);
		final DataSourceTextField descriptionField = new DataSourceTextField("description",
				messages.taskDescriptionLabel(), 350, true);
		final DataSourceTextField priorityField = new DataSourceTextField("priority", messages.taskPriorityLabel());
		final DataSourceDateField expectedStartDateField = new DataSourceDateField("expectedStartDate",
				messages.taskExpectedStartEndDateLabel());
		final DataSourceDateField expectedEndDateField = new DataSourceDateField("expectedEndDate",
				messages.taskEndDateLabel());
		final DataSourceTextField affectedUserUidField = new DataSourceTextField("affectedUser",
				messages.taskAffectedUserLabel());
		final DataSourceTextField statusField = new DataSourceTextField("status", messages.taskStatusLabel());
		dataSource.setFields(nameField, descriptionField, priorityField, expectedStartDateField, expectedEndDateField,
				affectedUserUidField, statusField);

		final DynamicForm form = new DynamicForm();

		form.setDataSource(dataSource);
		form.setUseAllDataSourceFields(true);
		form.setTitleWidth(150);
		final TextAreaItem descriptionItem = new TextAreaItem("description");
		descriptionItem.setWidth(300);
		descriptionItem.setHeight(100);
		final SelectItem priorityItem = new SelectItem("priority");
		priorityItem.setValueMap(PRIORITY.LOW.toString(), PRIORITY.MEDIUM.toString(), PRIORITY.HIGH.toString());
		priorityItem.setDefaultValue(PRIORITY.MEDIUM.toString());
		final SelectItem statusItem = new SelectItem("status");
		statusItem.setValueMap(STATUS.PENDING.toString(), STATUS.PROGRESS.toString(), STATUS.COMPLETE.toString());
		statusItem.setDefaultValue(STATUS.PENDING.toString());

		final SelectItem affectedUserItem = new SelectItem("affectedUser");
		affectedUserItem.setValueMap(teamMembersMap_loginToUser.keySet().toArray(new String[0]));
		final TextItem nameItem = new TextItem("name");
		nameItem.setWidth(220);
		final DateItem expectedStartDateItem = new DateItem("expectedStartDate");
		expectedStartDateItem.setUseTextField(true);
		expectedStartDateItem.setDisplayFormat(DateDisplayFormat.TOEUROPEANSHORTDATE);

		final DateItem expectedEndDateItem = new DateItem("expectedEndDate");
		expectedEndDateItem.setUseTextField(true);
		expectedEndDateItem.setDisplayFormat(DateDisplayFormat.TOEUROPEANSHORTDATE);

		final ButtonItem validateItem = new ButtonItem();
		validateItem.setTitle(messages.modalBoxOkLabel());

		final com.smartgwt.client.widgets.Window window = new com.smartgwt.client.widgets.Window();
		window.setTitle(taskRecord != null ? messages.editionBoxLabel() : messages.creationBoxLabel());
		window.setIsModal(true);
		window.setShowModalMask(true);
		window.centerInPage();
		form.setHeight100();
		form.setPadding(5);
		window.setWidth(470);
		window.setHeight(350);
		window.addItem(form);
		window.setShowCustomScrollbars(false);

		validateItem.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {

			@Override
			public void onClick(final com.smartgwt.client.widgets.form.fields.events.ClickEvent event) {
				if (form.validate()) {
					final UiTask uiTaskToPersist = new UiTask();
					LOG.fine("Save : " + nameItem.getValueAsString());
					if (taskRecord != null) {
						uiTaskToPersist.setUid(taskRecord.getInnerUiTask().getUid());
					}
					uiTaskToPersist.setName(nameItem.getValueAsString());
					uiTaskToPersist.setDescription(descriptionItem.getValueAsString());
					if (expectedEndDateItem.getValueAsDate() != null) {
						uiTaskToPersist.setExpectedEndDate(expectedEndDateItem.getValueAsDate());
					}
					if (expectedStartDateItem.getValueAsDate() != null) {
						uiTaskToPersist.setExpectedStartDate(expectedStartDateItem.getValueAsDate());
					}
					uiTaskToPersist.setPriority(PRIORITY.valueOf(priorityItem.getValueAsString()));
					uiTaskToPersist.setStatus(STATUS.valueOf(statusItem.getValueAsString()));
					uiTaskToPersist.getAffectedUsers().clear();
					if (taskRecord == null) {
						uiTaskToPersist.setCreator(connectedUser);
					} else {
						final UIUser creator = new UIUser();
						creator.setUid(taskRecord.getCreatorUid());
						uiTaskToPersist.setCreator(creator);
					}
					if (affectedUserItem.getValueAsString() != null) {
						final UIUser affectedUser = new UIUser();
						LOG.fine("AffectedUser : " + affectedUserItem.getValueAsString());
						affectedUser.setUid(teamMembersMap_loginToUser.get(affectedUserItem.getValueAsString())
								.getUid());
						uiTaskToPersist.getAffectedUsers().add(affectedUser);
					}
					LOG.log(Level.FINE, "ExpectedStartDate : " + uiTaskToPersist.getExpectedStartDate());
					async.saveTask(uiTaskToPersist, new AsyncCallback<UiTask>() {
						@Override
						public void onSuccess(final UiTask result) {
							window.clear();
							refreshTaskList(selectedUser);
						}

						@Override
						public void onFailure(final Throwable caught) {
							alert(caught.getMessage());
						}
					});
				}
			}
		});

		form.setFields(nameItem, descriptionItem, priorityItem, expectedStartDateItem, expectedEndDateItem,
				affectedUserItem, statusItem, validateItem);

		if (taskRecord != null) {
			// Initialise les valeurs avec celles de la tâches passée en
			// paramètre "edition"
			form.editRecord(taskRecord);
		} else {
			// création
			form.editNewRecord();
		}

		window.show();

	}

	private static void showComments(final String taskUid) {
		final com.smartgwt.client.widgets.Window commentWindow = new com.smartgwt.client.widgets.Window();
		commentWindow.setTitle(messages.commmentsLabel());
		commentWindow.setWidth(600);
		commentWindow.setHeight(500);
		commentWindow.setIsModal(true);
		commentWindow.setShowModalMask(true);
		commentWindow.centerInPage();

		commentGrid.setWrapCells(true);
		commentGrid.setFixedRecordHeights(false);
		commentGrid.setWidth100();
		commentGrid.setHeight(330);
		commentGrid.setShowRecordComponents(true);
		commentGrid.setShowRecordComponentsByCell(true);
		commentGrid.setShowAllRecords(true);
		commentGrid.setSelectionType(SelectionStyle.NONE);

		final ListGridField creationDateField = new ListGridField("creationDate", "Date");
		creationDateField.setWidth(60);
		creationDateField.setType(ListGridFieldType.DATE);
		creationDateField.setCellFormatter(getCellDateFormater("creationDate"));
		creationDateField.setAlign(Alignment.LEFT);

		final ListGridField writerField = new ListGridField("writer", "Redacteur");
		writerField.setWidth(70);
		writerField.setShowDefaultContextMenu(false);

		final ListGridField textField = new ListGridField("text", "Commentaire");
		textField.setShowDefaultContextMenu(false);

		final ListGridField deleteButton = new ListGridField("deleteButton", messages.deleteTask());
		deleteButton.setWidth(60);
		deleteButton.setAlign(Alignment.CENTER);
		deleteButton.setShowDefaultContextMenu(false);

		commentGrid.setFields(creationDateField, writerField, textField, deleteButton);
		final VLayout layout = new VLayout(5);
		layout.addMember(commentGrid);

		listComments(commentGrid, taskUid);

		final TextAreaItem descriptionItem = new TextAreaItem("description");
		descriptionItem.setWidth(500);
		descriptionItem.setRequired(true);

		final ButtonItem validateItem = new ButtonItem();
		validateItem.setTitle(messages.modalBoxOkLabel());

		final DynamicForm form = new DynamicForm();
		form.setFields(descriptionItem, validateItem);

		validateItem.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {

			@Override
			public void onClick(final com.smartgwt.client.widgets.form.fields.events.ClickEvent event) {
				if (form.validate()) {
					final UIComment commentToSave = new UIComment();
					commentToSave.setText(descriptionItem.getValueAsString());
					commentToSave.setTaskUid(taskUid);
					commentToSave.setWriter(connectedUser);
					async.createComment(commentToSave, new AsyncCallback<Void>() {
						@Override
						public void onFailure(final Throwable caught) {
							alert(caught.getMessage());
						};

						@Override
						public void onSuccess(final Void result) {
							listComments(commentGrid, taskUid);
							descriptionItem.clearValue();
						};
					});
				}

			}
		});

		layout.addMember(form);
		commentWindow.addItem(layout);
		commentWindow.show();
	}

	private static void listComments(final ListGrid commentGrid, final String taskUid) {

		async.getComments(taskUid, new AsyncCallback<List<UIComment>>() {

			@Override
			public void onSuccess(final List<UIComment> result) {
				commentGrid.setData(TaskData.UICommentList2CommentRecordArray(result));
			}

			@Override
			public void onFailure(final Throwable caught) {
				alert(caught.getMessage());
			}
		});

	}

	// Affiche le message d'erreur � l'utilisateur
	private static void alert(final String errorMsg) {
		SC.warn(errorMsg);
	}

	private static Canvas getSmartGwtCanvasTaskList() {

		final Canvas canvas = new Canvas();
		taskGrid.setWidth(LIST_WIDTH);
		taskGrid.setHeight(600);
		taskGrid.setShowRecordComponents(true);
		taskGrid.setShowRecordComponentsByCell(true);
		taskGrid.setShowAllRecords(true);
		taskGrid.setSelectionType(SelectionStyle.NONE);
		taskGrid.setWrapCells(true);
		taskGrid.setFixedRecordHeights(false);

		final ListGridField taskName = new ListGridField("name", messages.taskNameLabel());
		taskName.setWidth(170);
		final ListGridField description = new ListGridField("description", messages.taskDescriptionLabel());
		description.setWidth(250);
		final ListGridField priority = new ListGridField("priority", messages.taskPriorityLabel());
		priority.setWidth(60);

		final ListGridField expectedStartDate = new ListGridField("expectedStartDate",
				messages.taskExpectedStartEndDateLabel());
		expectedStartDate.setWidth(140);
		expectedStartDate.setType(ListGridFieldType.DATE);
		expectedStartDate.setCellFormatter(getCellDateFormater("expectedStartDate"));
		expectedStartDate.setAlign(Alignment.LEFT);

		final ListGridField expectedEndDate = new ListGridField("expectedEndDate", messages.taskEndDateLabel());
		expectedEndDate.setWidth(140);
		expectedEndDate.setType(ListGridFieldType.DATE);
		expectedEndDate.setCellFormatter(getCellDateFormater("expectedEndDate"));
		expectedEndDate.setAlign(Alignment.LEFT);
		final ListGridField creator = new ListGridField("creator", messages.taskCreatorLabel());
		creator.setWidth(70);
		final ListGridField affectedUser = new ListGridField("affectedUser", messages.taskAffectedUserLabel());
		affectedUser.setWidth(150);
		final ListGridField status = new ListGridField("status", messages.taskStatusLabel());
		status.setWidth(70);
		final ListGridField editButton = new ListGridField("editButton", messages.editTask() + "/"
				+ messages.addComment() + "/" + messages.deleteTask());
		editButton.setWidth(160);
		editButton.setAlign(Alignment.CENTER);
		editButton.setShowDefaultContextMenu(false);
		taskGrid.setFields(taskName, description, priority, expectedStartDate, expectedEndDate, creator, affectedUser,
				status, editButton);
		canvas.addChild(taskGrid);
		refreshTaskList(connectedUser);
		return canvas;

	}

}
